package librairies.arborescence.interfaces;

import librairies.exception.ArbreCyclique;
import librairies.exception.GreffeDeSousArbre;
import librairies.exception.SousArbreIncoherent;
import librairies.liste.interfaces.IListe;

/**
 * interface d'un arbre.
 * 
 * @author mlozach
 * @param <E> type de l'element dans l'arbre.
 */
public interface IArbre<E> 
{
	/**
	 * retourne la valeur du noeud.
	 * @return E la valeur.
	 */
	public E getVal();
	
	/**
	 * modifie la valeur du noeud.
	 * @param e la nouvelle valeur.
	 * @return retourne l'ancienne valeur.
	 */
	public E setVal(E e); 
	
	/**
	 * permet de savoir si c'est une feuille.
	 * @return vrai si il n'y a pas de fils.
	 */
	public boolean isLeaf(); 
	
	/**
	 * permet de connaitre le nombre de noeud dans l'arbre.
	 * @return le nombre de noeud.
	 */
	public int familySize(); 
	
	/**
	 * permet de connaitre la hauteur de l'arbre.
	 * @return la hauteur.
	 */
	public int height();
	
	/**
	 * permet de retourner le pere du neoud.
	 * @return le pere.
	 */
	public IArbre<E> father();
	
	/**
	 * cherche le pere des pere.
	 * @return le 1er pere.
	 */
	public IArbre<E> ancestor();
	
	/**
	 * retourne la liste des enfants de ce noeud.
	 * @return la liste des enfants.
	 */
	public IListe<? extends IArbre<E>> children();
	
	/**
	 * retourne la liste des peres des peres.
	 * @return la liste des ces peres.
	 */
	public IListe<? extends IArbre<E>> ancestors();
	
	/**
	 * recherche ces frere et soeur potentielle.
	 * @return la liste des ces freres et soeur.
	 */
	public IListe<? extends IArbre<E>> brothers();
	
	/**
	 * retourne la liste de tous les noeuds en desous de celui ci jusqu'au niveau n
	 * @param n le nombre de niveau a descendre
	 * @return la liste des noeuds
	 */
	public IListe<? extends IArbre<E>> gen(int n);
	
	/**
	 * permet de savoir si un sous arbre appartient a cette arbre.
	 * @param a le sous arbre
	 * @return vrai si le sous arbre existe.
	 */
	public boolean contains(IArbre<E> a);
	
	/**
	 * permet de supprimer tous les fils directe
	 * @return la liste des fils supprimer
	 */
	public IListe<? extends IArbre<E>> cutAll();
	
	/**
	 * permet de supprimer un fils
	 * @param i le numero du fils
	 * @return le fils supprimer
	 * @throws IndexOutOfBoundsException
	 */
	public IArbre<E> cutChild(int i) throws IndexOutOfBoundsException;
	
	/**
	 * permet de recuperer un fils
	 * @param i le numero du fils
	 * @return le fils demander
	 * @throws IndexOutOfBoundsException
	 */
	public IArbre<E> getChild(int i) throws IndexOutOfBoundsException; 
	
	/**
	 * permet d ajouter un fils
	 * @param a le fils a ajouter
	 * @return this.
	 * @throws NullPointerException
	 * @throws ArbreCyclique
	 * @throws GreffeDeSousArbre
	 * @throws SousArbreIncoherent
	 */
	public IArbre<E> addChild(IArbre<E> a) throws NullPointerException, ArbreCyclique, GreffeDeSousArbre, SousArbreIncoherent;
	
	/**
	 * permet d'ajouter un fils a une position donner
	 * @param i la position du fils
	 * @param a le nouveau fils
	 * @return this.
	 * @throws NullPointerException
	 * @throws IndexOutOfBoundsException
	 * @throws ArbreCyclique
	 * @throws GreffeDeSousArbre
	 * @throws SousArbreIncoherent
	 */
	public IArbre<E> addChild(int i, IArbre<E> a) throws NullPointerException,
			IndexOutOfBoundsException, ArbreCyclique, GreffeDeSousArbre, SousArbreIncoherent;
	
	/**
	 * permet de recuperer les valeurs de l'arbre en commencent par lui-meme
	 * @return la liste de valeur
	 */
	public IListe<E> prefixe(); 
	
	/**
	 * permet de recuperer les valeurs de l'arbre en finissant par lui-meme
	 * @return la liste de valeur
	 */
	public IListe<E> postfixe(); 
	
	/**
	 * ????????
	 * @return la liste des valeurs.
	 */
	public IListe<E> largeur(); 
}